/*
 * Copyright 2015 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.benmei.ntlive.server.netty;

import com.benmei.ntlive.constant.Constants;
import com.benmei.ntlive.entity.ClassRoomEntryLog;
import com.benmei.ntlive.service.LiveService;
import com.benmei.ntlive.vo.Room;
import com.benmei.ntlive.vo.Session;
import io.netty.util.concurrent.ScheduledFuture;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Channel Repository using HashMap
 *
 * @author Jibeom Jung
 */
public class SessionRepository {
    private static Logger logger = LoggerFactory.getLogger(SessionRepository.class);
    @Autowired
    private LiveService liveService;
    // key:roomId,value:Room
    private Map<Integer, Room> roomMap = new ConcurrentHashMap<Integer, Room>();

    /**
     * resive by C.H on 2018/10/29 13:23
     * 增加：taskMap  存放心跳任务
     */
    private  Map<String, ScheduledFuture> taskMap = new ConcurrentHashMap<String, ScheduledFuture>();

    public void put(Integer key, Room value) {
        roomMap.put(key, value);
    }

    public Room get(Integer roomId) {
        return roomMap.get(roomId);
    }

    public Map<String, ScheduledFuture> getTaskMap() {
        return taskMap;
    }

    public void setTaskMap(Map<String, ScheduledFuture> taskMap) {
        this.taskMap = taskMap;
    }

    // 根据客户端ip和端口号移除session
    public void remove(String endPoint) {
        Set<Integer> keys = roomMap.keySet();
        Iterator<Integer> keyIter = keys.iterator();
        while (keyIter.hasNext()) {
            Integer key = keyIter.next();
            Room room = roomMap.get(key);
            // 如果endPoint是学生，则移除学生；如果是老师就移除老师。
            if (room.getStudent() != null && room.getStudent().getChannel().remoteAddress().toString().equals(endPoint)) {
                ClassRoomEntryLog roomLog = new ClassRoomEntryLog();
                roomLog.setRoom_id(room.getRoomId());
                roomLog.setEvent_type("closeTcpSession");
                roomLog.setEvent_date(new Date());
                roomLog.setUser_id(room.getStudent().getUser().getId());
                roomLog.setUser_role(Constants.UserRole.STUDENT);
                roomLog.setClient_os_type(room.getStudent().getUser().getClientOsType());
                roomLog.setDetail("Closed TCP user session,endPoint:" + endPoint);
                liveService.roomLog(roomLog);
                room.setStudent(null);
            } else if (room.getTeacher() != null && room.getTeacher().getChannel().remoteAddress().toString().equals(endPoint)) {
                ClassRoomEntryLog roomLog = new ClassRoomEntryLog();
                roomLog.setRoom_id(room.getRoomId());
                roomLog.setEvent_type("closeTcpSession");
                roomLog.setEvent_date(new Date());
                roomLog.setUser_id(room.getTeacher().getUser().getId());
                roomLog.setUser_role(Constants.UserRole.TEACHER);
                roomLog.setClient_os_type(room.getTeacher().getUser().getClientOsType());
                roomLog.setDetail("ClosedTCP user session,endPoint:" + endPoint);
                liveService.roomLog(roomLog);
                room.setTeacher(null);
            } else {
                logger.info("连接" + endPoint + "没有建立TcpSession的情况下被关闭");
            }

            // 如果教室是空的就移除教室
            if (room.isEmpty()) {
                ClassRoomEntryLog roomLog = new ClassRoomEntryLog();
                roomLog.setRoom_id(room.getRoomId());
                roomLog.setEvent_type("closeTcpRoomSession");
                roomLog.setEvent_date(new Date());
                roomLog.setDetail("关闭 TCP Room session,roomId:" + room.getRoomId());
                liveService.roomLog(roomLog);
                roomMap.remove(key);
            }
        }
    }

    public int size() {
        return this.roomMap.size();
    }

    public Session getSessionByKey(String endPoint) {
        Set<Integer> keys = roomMap.keySet();
        Iterator<Integer> keyIter = keys.iterator();
        Session session = null;
        while (keyIter.hasNext()) {
            Integer key = keyIter.next();
            Room room = roomMap.get(key);
            if (room.getStudent() != null && room.getStudent().getChannel().remoteAddress().toString().equals(endPoint)) {
                session = room.getStudent();
                break;
            } else if (room.getTeacher() != null && room.getTeacher().getChannel().remoteAddress().toString().equals(endPoint)) {
                session = room.getTeacher();
                break;
            }
        }
        return session;
    }
}
